'use strict';

Object.defineProperty(exports, "__esModule", {
    value: true
});
exports.genModel = undefined;

var _toConsumableArray2 = require('babel-runtime/helpers/toConsumableArray');

var _toConsumableArray3 = _interopRequireDefault(_toConsumableArray2);

var _defineProperty2 = require('babel-runtime/helpers/defineProperty');

var _defineProperty3 = _interopRequireDefault(_defineProperty2);

var _extends2 = require('babel-runtime/helpers/extends');

var _extends3 = _interopRequireDefault(_extends2);

var _objectWithoutProperties2 = require('babel-runtime/helpers/objectWithoutProperties');

var _objectWithoutProperties3 = _interopRequireDefault(_objectWithoutProperties2);

var _generateEventEmitter = require('./generateEventEmitter');

var _update = require('./update');

var update = _interopRequireWildcard(_update);

var _get = require('lodash/get');

var _get2 = _interopRequireDefault(_get);

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var noop = function noop() {};
var genModel = function genModel() {
    var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};

    var _ref$defaultData = _ref.defaultData,
        defaultData = _ref$defaultData === undefined ? function () {
        return {};
    } : _ref$defaultData,
        _ref$log = _ref.log,
        log = _ref$log === undefined ? noop : _ref$log,
        showLog = _ref.showLog,
        other = (0, _objectWithoutProperties3.default)(_ref, ['defaultData', 'log', 'showLog']);

    var event = (0, _generateEventEmitter.generateEventEmitter)();
    var rst = {
        data: defaultData()
    };

    var _changeData = function _changeData() {
        var args = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
        var path = arguments[1];
        var method = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'update';
        var action = args.action,
            param = args.param;

        if (!action) {
            console.warn('action\u4E0D\u80FD\u4E3A\u7A7A');
        }
        var oldData = rst.data;
        if (method === 'replace') {
            rst.data = (0, _extends3.default)({}, param);
        } else {
            var target = path ? (0, _get2.default)(oldData, path) : oldData;
            var newTarget = update[method](target, param);
            rst.data = path ? update.update(oldData, (0, _defineProperty3.default)({}, path, newTarget)) : newTarget;
        }
        showLog && log('model.changeData', args, 'path=', path);
        event.emit('change', oldData);
    };
    return (0, _extends3.default)({}, other, {
        getData: function getData(path, defVal) {
            return path ? (0, _get2.default)(rst.data, path, defVal) : rst.data;
        },
        resetData: function resetData() {
            var data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : defaultData();

            _changeData({
                action: 'resetData',
                param: data
            }, null, 'replace');
        },
        onChange: function onChange(ns, fn) {
            return event.onOne('change', ns, fn);
        },
        offChange: function offChange(ns, fn) {
            return event.off('change', ns, fn);
        },
        off: function off() {
            return event.off.apply(event, arguments);
        },
        offAll: function offAll() {
            return event.removeAllListeners();
        },
        changeData: function changeData() {
            if (arguments.length === 2) {
                return _changeData(arguments.length <= 1 ? undefined : arguments[1], arguments.length <= 0 ? undefined : arguments[0]);
            }
            return _changeData(arguments.length <= 0 ? undefined : arguments[0]);
        },
        changeDataNoEmit: function changeDataNoEmit() {
            var _this = this;

            for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
                args[_key] = arguments[_key];
            }

            setTimeout(function () {
                _this.changeData.apply(_this, (0, _toConsumableArray3.default)(args));
            }, 1);
        },
        nextTick: function nextTick(fn) {
            setTimeout(function () {
                fn && fn();
            }, 1);
        },
        changeDataUseImmutable: function changeDataUseImmutable(arg) {
            return _changeData(arg, null, 'updateRaw');
        }
    });
};
exports.genModel = genModel;
exports.default = genModel;